package com.heima.search.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.common.Threadlocals.UserThreadLocalUtil;
import com.heima.common.dto.PageResponseResult;
import com.heima.common.dto.ResponseResult;
import com.heima.common.dto.User;
import com.heima.search.dto.ApArticleSearchDto;
import com.heima.search.entity.ApArticleSearch;
import com.heima.search.repository.ApUserSearchRepository;
import com.heima.search.service.IApUserSearchService;
import com.heima.search.service.IArticleSearchService;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: itheima
 * @create: 2022-07-12 11:02
 */
@Service
public class ArticleSearchServiceImpl implements IArticleSearchService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;


    @Autowired
    private IApUserSearchService userSearchService;


    /**
     GET /app_info_article/_search
     {
     "query": {
     "bool": {
     "must": [
     {
     "match": {
     "all": "支付宝"
     }
     }
     ],
     "filter": [
     {
     "term": {
     "isDelete": "false"
     }
     }
     ]
     }
     },
     "from": 0,
     "size": 20,
     "highlight": {
     "pre_tags": "<font color='red'>",
     "post_tags": "</font>",
     "fields":{"title": {}}
     },
     "sort": [
     {
     "publishTime": {
     "order": "desc"
     }
     }
     ]
     }
     **/


    /**
     * 根据关键字模糊查询文章列表
     *
     * @param dto 查询条件
     * @return 文章分页结果
     */
    @Override
    public ResponseResult search(ApArticleSearchDto dto) {
        try {
            //1.构建SearchRequest搜索请求对象 封装查询索引库名称
            SearchRequest searchRequest = new SearchRequest("app_info_article");

            //2.构建SearchSourceBuilder请求体参数对象  封装请求参数
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            //2.1 封装查询条件参数
            sourceBuilder.query(basicQuery(dto));
            //2.2 设置分页参数
            Long from = (dto.getPage() - 1) * dto.getSize();
            sourceBuilder.from(from.intValue()).size(dto.getSize());
            //2.3 设置排序方式
            sourceBuilder.sort("publishTime", SortOrder.DESC);
            //2.4 TODO 作业：设置高亮
            //2.5 去除不需要的字段（响应结果字段过滤）
            sourceBuilder.fetchSource(null, new String[]{"isDelete", "isDown"});

            //3.将SearchSourceBuilder加入到SearchRequest对象中
            searchRequest.source(sourceBuilder);

            //4.执行检索
            SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

            //5.封装分页结果
            //5.1 获取总记录数
            long total = response.getHits().getTotalHits().value;
            //5.2 解析响应业务数据
            SearchHit[] hits = response.getHits().getHits();
            List<ApArticleSearch> list = new ArrayList<>();
            if (hits != null && hits.length > 0) {
                for (SearchHit hit : hits) {
                    String sourceAsString = hit.getSourceAsString();
                    ApArticleSearch apArticleSearch = JSON.parseObject(sourceAsString, ApArticleSearch.class);
                    list.add(apArticleSearch);
                }
            }
            //6.TODO 记录用户搜索历史
            User user = UserThreadLocalUtil.get();
            if (user != null) {
                userSearchService.saveSearchRecord(dto.getSearchWords(), user.getUserId(), dto.getEquipmentId());
            }
            return new PageResponseResult(dto.getPage(), dto.getSize(), total, list);
        } catch (IOException e) {
        }
        return null;
    }


    /**
     * 构建查询条件
     *
     * @param dto 查询入参
     * @return 查询条件对象
     */
    private QueryBuilder basicQuery(ApArticleSearchDto dto) {
        //构建bool查询对象
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        if (StringUtils.isNotBlank(dto.getSearchWords())) {
            boolQuery.must(QueryBuilders.matchQuery("all", dto.getSearchWords()));
        } else {
            boolQuery.must(QueryBuilders.matchAllQuery());
        }
        boolQuery.filter(QueryBuilders.termQuery("isDelete", false));
        boolQuery.filter(QueryBuilders.termQuery("isDown", false));
        return boolQuery;
    }
}
